#include<iostream>

#include"Socket.hpp"
#include"Protocol.hpp"
#include"Calculate.hpp"
#include<ctime>
#include<cstdlib>
#include<unistd.h>


int main(int argc,char* argv[])
{
    if(argc!=3)
    {
        std::cout<<"Usage: "<<argv[0]<<" serverip serverport "<<std::endl;
    }
    std::string serverip=argv[1];
    uint16_t serverport=std::stoi(argv[2]);
    Net_Work::Socket* conn=new Net_Work::TcpSocket();
    if(!conn->BuidConnectSocketMethod(serverip,serverport))
    {
        std::cerr<<"connect "<<serverip<<":"<<serverport<<"faild"<<std::endl;
    }
    std::cout<<"connect "<<serverip<<":"<<serverport<<"succeed"<<std::endl;

    // std::string message="hello world";
    // write(s->GetSocket(),message.c_str(),message.size());

    //send和sendto和write关系
    //sleep(10);
    std::unique_ptr<Proctocol::Factory> factory = std::make_unique<Proctocol::Factory>();
    
    srand(time(nullptr)^getpid());
    const std::string opers="+-*/%^=&";

    while(true)
    {
        int x=rand()%100;
        usleep(rand()%7777);
        int y=rand()%100;
        char oper=opers[rand()%opers.size()];
        std::shared_ptr<Proctocol::Request> req = factory->BuildRequest(x,y,oper);
        // 1.序列化
        std::string requeststr;
        req->Serialize(&requeststr);
        std::cout<<requeststr<<std::endl;
        //for test
        std::string testreq;
        testreq+=" ";
        testreq+="=";

        // 2.添加报头
        requeststr=Proctocol::Encode(requeststr);

        // 3.发送
        conn->Send(requeststr);
        // 4.接受
        std::string responsestr;
        while(true)
        {
            // 5.读取响应
            conn->Recv(&responsestr, 1024);
            //std::cout<<responsestr<<std::endl; 
            std::string response;
            // 6.报文进行解析
            if (!Proctocol::Decode(responsestr, &response))
                continue;
            // 7.打印
            auto resp=factory->BuildResponse();
            resp->Deserialize(response);
            std::cout<<testreq<<resp->Getresult()<<"["<<resp->Getcode()<<"]"<<std::endl;
            break;
        }
        sleep(1);
    }
    conn->CloseSockfd();
    return 0;
}